/* Includes--------------------------------------------- */
#include "drv_spi.h"

/* Define----------------------------------------------- */
#define SPI_PERIPH           SPI1
#define SPI_CLOCK        RCU_SPI1
#define SPI_TIMEOUT          1000

/* Private funtion delaration--------------------------- */
/* Private variables------------------------------------ */
static spi_parameter_struct spi_struct;

/* External variables----------------------------------- */
/* External functions----------------------------------- */
void DrvSPIInit(void) {
    rcu_periph_clock_enable(RCU_GPIOB);
    gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, GPIO_PIN_0);
    gpio_output_options_set(GPIOB,GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0);
//    gpio_af_set(GPIOB, GPIO_AF_0, GPIO_PIN_12);
    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);
    gpio_output_options_set(GPIOB,GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);
    gpio_af_set(GPIOB, GPIO_AF_0, GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);

    rcu_periph_clock_enable(SPI_CLOCK);
    spi_i2s_deinit(SPI_PERIPH);
    spi_struct_para_init(&spi_struct);

    spi_struct.device_mode = SPI_MASTER;
    spi_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
    spi_struct.frame_size = SPI_FRAMESIZE_8BIT;
    spi_struct.nss = SPI_NSS_SOFT;
    spi_struct.endian = SPI_ENDIAN_MSB;
    spi_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;
    spi_struct.prescale = SPI_PSC_256;
    spi_init(SPI_PERIPH, &spi_struct);
//    spi_nss_output_enable(SPI_PERIPH);
//    spi_nss_internal_low(SPI_PERIPH);
    spi_fifo_access_size_config(SPI_PERIPH, SPI_BYTE_ACCESS);
//    spi_crc_polynomial_set(SPI_PERIPH, 7);
//    spi_crc_on(SPI_PERIPH);
    spi_enable(SPI_PERIPH);
}

void DrvSPISetSpeed(uint8_t speed) {
    if (speed == 0) {
        spi_struct.prescale = SPI_PSC_256;//Low speed
    } else {
        spi_struct.prescale = SPI_PSC_8;//High speed
    }
    spi_init(SPI_PERIPH, &spi_struct);
    spi_enable(SPI_PERIPH);
}

void DrvSPIWrite(uint8_t data) {
    uint32_t timeout;

    timeout = SPI_TIMEOUT;
    while (!spi_i2s_flag_get(SPI_PERIPH, SPI_FLAG_TBE) && timeout--);
    spi_i2s_data_transmit(SPI_PERIPH, data);
}

uint8_t DrvSPIRead(void) {
    uint32_t timeout;

    timeout = SPI_TIMEOUT;
    while (!spi_i2s_flag_get(SPI_PERIPH, SPI_FLAG_RBNE) && timeout--);
    return spi_i2s_data_receive(SPI_PERIPH);
}

/* Private functions------------------------------------ */
/* End of file------------------------------------------ */
